﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CharmL.Helper;

namespace CharmL {
    public class HashItem {
        public List<int> ItemSet { get; set; }
        public int Support { get; set; }
        public int HashVal { get; set; }

        public HashItem(List<int> list, int lit, int iSup, int iHval) {
            ItemSet = list;
            if (lit != -1) ItemSet.Add(lit);
            ItemSet.Sort();
            //ItemSet.AddWithOrder(lit);
            Support = iSup;
            HashVal = iHval;            
        }

        public bool SubSet(HashItem hashItem) {
            int i, j;
            if (ItemSet.Count > hashItem.ItemSet.Count) return false;
            for (i = 0, j = 0; i < ItemSet.Count && j < hashItem.ItemSet.Count; ) {
                if (ItemSet[i] < hashItem.ItemSet[j]) return false;
                else if (ItemSet[i] > hashItem.ItemSet[j]) ++j;
                else {
                    ++i;
                    ++j;
                }
            }
            if (i < ItemSet.Count) return false;
            return true;
            //if (iset.size() > ia->iset.size()) return false;
            //for (i = 0, j = 0; i < iset.size() && j < ia->iset.size(); ) {
            //    if (iset[i] < ia->iset[j]) return false;
            //    else if (iset[i] > ia->iset[j]) ++j;
            //    else {
            //        ++i;
            //        ++j;
            //    }
            //}
            //if (i < iset.size()) return false;
            //return true;           
        }

        public static int Compare(HashItem itemA, HashItem itemB) {
            if (itemA.Support > itemB.Support) return 1;
            else if (itemA.Support < itemB.Support) return -1;
            else if (itemA.ItemSet.Count > itemB.ItemSet.Count) return 1;
            else if (itemA.SubSet(itemB)) return 0;
            else if (itemA.ItemSet.Count < itemB.ItemSet.Count) return -1;
            else return 1;

            //if (ia->support() > ib->support()) return 1;
            //else if (ia->support() < ib->support()) return -1;
            //else if (ia->itemset().size() > ib->itemset().size()) return 1;
            //else if (ia->subset(ib)) return 0;
            //else if (ia->itemset().size() < ib->itemset().size()) return -1;
            //else return 1;            
        }

        void WriteOut(StreamWriter stream) {
            stream.WriteLine(string.Format("{0} - {1} {2}", ItemSet, Support, HashVal));
        }
    }

    //    class cHashItem{
    //private:
    //   vector<int> iset;
    //   int sup;
    //   int hval;
    //public:
    //   cHashItem(vector<int> &iary, int lit, int isup, int ihval);
    //   int hashval() { return hval;}
    //   int support() { return sup; }
    //   vector<int> &itemset() { return iset; }
    //   bool subset (cHashItem *ia);
    //   static int compare (cHashItem *ia, cHashItem *ib);
    //   friend ostream& operator << (ostream& fout, cHashItem& lst);
    //};

}
